#!/usr/bin/python
# vi: et sw=2
#
# Control class

import pygtk
import gtk
import gobject

import sys

from AppletGConfig import *

from AppletView import *
from PulseGlib  import *

# Controller
class PulseTray(gtk.StatusIcon):
  def __init__(self):
    gtk.StatusIcon.__init__(self)
    self.connect("size-changed", self.on_size_changed)
    self.connect("activate", self.on_activate)
    self.connect("popup-menu", self.on_popup_menu)

    self.iconTheme = gtk.icon_theme_get_default()

    self.settings = AppletGConfig()
    self.settings.connect(
        ["layout", "theme", "use_xml_icons"],
        self.update_view_settings
    )   

    # FIXME get from settings
    self.defaultSinkIndex = 0

    self.menu = gtk.Menu()
    item = gtk.MenuItem("Quit")
    item.connect("activate", gtk.main_quit)
    self.menu.add(item)
    self.menu.show_all()

    self.model = AppletModel()
    self.model.connect("data-changed", self.on_model_data_changed)
    self.view  = AppletView(self.settings.get_view_settings(), self.model)
    # FIXME doesn't do nothing
    self.view.icon_size = 48

    self.iconName = "network-wired-disconnected-symbolic"
    self.traySize = None

    self.pulse = PulseGlib()
    self.pulse.connect("context-ready", self.on_pulse_context_ready)
    self.pulse.connect("context-failed", self.on_pulse_context_failed)
    self.pulse.connect("context-terminated", self.on_pulse_context_terminated)

    self.connect("button-press-event", self.button_press_event)
    #self.connect("key-press-event", self.key_press_event)

    self.pulse.pulseConnect()

    print "PulseTray is now loaded"
    return

    #
    # __init__ end
    #

  #
  # Functions

  def show_view(self):
    [window, rect, orient] = self.get_geometry()
    [x, y, w, h] = rect

    [vw, vh] = self.view.get_size()

    if vh == 0 and vw == 0:
      self.view.show_all()
      [vw, vh] = self.view.get_size()

    #print x, y, w, h
    #print vw, vh
    if orient == gtk.ORIENTATION_HORIZONTAL:
      corr_x = 0 

      if y < h:
        # UP
        self.view.move(x + corr_x, y + h)
      else:
        # DOWN
        self.view.move(x + corr_x, y - vh)
    else:
      corr_y = 0

      if x < w:
        # LEFT
        self.view.move(x + w, y + corr_y)
      else:
        # RIGHT
        self.view.move(x - vw, y + corr_y)

    #print "Focus grab"
    #gtk.gdk.keyboard_grab(self.window, True)
    #gtk.gdk.pointer_grab(
    #          self.window,
    #          True,
    #          gtk.gdk.BUTTON_PRESS_MASK
    #          #| gtk.gdk.BUTTON_RELEASE_MASK
    #)
    self.view.show_all()
    #
    # show_view end
    #

  def hide_view(self):
    #print "Focus release"
    #gtk.gdk.keyboard_ungrab()
    #gtk.gdk.pointer_ungrab()

    self.view.hide()
    #
    # hide_view end
    #

  def update_tray_icon(self):
    if self.traySize:
      self.set_from_pixbuf(
        self.iconTheme.load_icon(
          self.iconName,
          self.traySize,
          gtk.ICON_LOOKUP_USE_BUILTIN
        )
      )
    pass

  def on_model_data_changed(self, model = None):
    if self.model.sink_count() > self.defaultSinkIndex:
      self.iconName = self.model.sink_get_volume_icon_name(
                        self.defaultSinkIndex
      )

      self.set_tooltip(
        "Master:\t" + \
        str(int(self.model.sink_get_volume(self.defaultSinkIndex))) + \
        "%\n\t\t" + \
        str(self.model.sink_get_volume_dB(self.defaultSinkIndex)) + \
        " dB"
      )
      self.update_tray_icon()
    pass

  def on_size_changed(self, status_icon, size, *userparam):
    self.traySize = size
    self.update_tray_icon()

    return True

  def on_activate(self, status_icon, *userparam):
    if self.view.get_property("visible") == True:
      self.hide_view()
      return True

    self.show_view()

    return True

  def on_popup_menu(self, status_icon, button, activate_time, *userparam):
    self.menu.popup(
        None,
        None,
        gtk.status_icon_position_menu,
        button,
        activate_time,
        status_icon
    )

    return True

  #
  # PulseAudio events

  def on_pulse_context_ready(self, pulse):
    if not self.traySize:
      self.set_from_stock(gtk.STOCK_CONNECT)
    else:
      self.update_tray_icon()

    self.model.set_pulse(pulse)

    self.connect("scroll-event", self.reroute_scroll_event)
    pass
 
    # 
    # on_pulse_context_ready end
    #

  def on_pulse_context_failed(self, pulse):
    if not self.traySize:
      self.set_from_stock(gtk.STOCK_DIALOG_WARNING)
    else:
      self.iconName = "network-wired-disconnected-symbolic"
      self.update_tray_icon()
    pass

    #
    # on_pulse_context_failed end
    #

  def on_pulse_context_terminated(self, pulse):
    if not self.traySize:
      self.set_from_stock(gtk.STOCK_CANCEL)
    else:
      self.iconName = "modem"
      self.update_tray_icon()
    pass
 
    # 
    # on_pulse_context_terminated end
    #

  #
  # Applet events

  def reroute_scroll_event(self, widget, event):
    # FIXME get index from configs
    index = 0

    if index >= self.model.sink_count():
      index = 0

    scroll = self.view.box.get_children()[index].scroll

    self.view.box.show_all()

    # FIXME Add left and right scroll
    if event.direction == gtk.gdk.SCROLL_DOWN:
      # This is too some kind bug in GTK ???
      scroll.emit("move-slider", gtk.SCROLL_PAGE_DOWN)
    elif event.direction == gtk.gdk.SCROLL_UP:
      scroll.emit("move-slider", gtk.SCROLL_PAGE_UP)

    # scroll.emit("scroll-event", event)
    # Does work only if view is showed once. Strange bug in GTK HScale???

    pass

    #
    # reroute_scroll_event end
    #

  def button_press_event(self, widget, event):
    if event.button == 2:
      if self.model.sink_count == 0:
        return True

      # FIXME get index from GConf
      index = 0

      if index >= self.model.sink_count():
        index = 0

      mute = self.view.box.get_children()[index].mute

      mute.emit("button-press-event", event);

      return True

    pass

    #
    # button_press_event end
    #

  def key_press_event(self, widget, event):
    if not event.type == gtk.gdk.KEY_PRESS:
      return False

    if event.keyval == 65307: # ESC
      self.hide_view()

    return True

    #
    # key_press_event end
    #

  #
  # Settings events

  def update_view_settings(self, client, *args, **kwags):
    self.view.update_settings(self.settings.get_view_settings())

    #
    # update_view_settings end
    #

  pass

  #
  # class PulseTray end
  #


if __name__ == "__main__":
  PulseTray()
  gtk.main()

